package demo;

/**
 * 基于数组实现的阻塞队列
 */

class MyBlockingQueue{
    private volatile int head = 0;
    private volatile int tail = 0;
    private volatile int size = 0;

    private String[] data=null;

    public MyBlockingQueue(int capacity){
        data=new String[capacity];
    }

    public void put(String s) throws InterruptedException {
        synchronized(this){
            if (size==data.length){
                this.wait();//如果wait在try catch里面，
                            // 此时应该用while 在wait唤醒之后判断是否继续执行 如t2
            }
            data[tail]=s;
            tail++;
            if (tail>=data.length){
                tail=0;
            }
            size++;

            this.notify();
        }
    }

    public String take() throws InterruptedException{
        String ret=null;
        synchronized(this){
            while (size==0){
                this.wait();
            }
            ret=data[head];
            head++;
            if (head>=data.length){
                head=0;
            }
            size--;

            this.notify();
        }
        return ret;
    }
}

public class demo2{
    public static void main(String[] args) {
        MyBlockingQueue queue=new MyBlockingQueue(1000);

        Thread t1=new Thread(()->{
           int i=1;
           while(true){
               try {
                   queue.put(i+"");
                   System.out.println("生产元素："+i);
                   i++;
                   //Thread.sleep(1000);
                   //生产慢点
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });

        Thread t2=new Thread(()->{
           while(true){
               try {
                   int cur=Integer.parseInt(queue.take());
                   System.out.println("取出元素："+ cur);
                   Thread.sleep(1000);
                   //生产快点，消费慢点
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });

        t1.start();
        t2.start();
    }
}
